#include <stdio.h>
#include <unistd.h>
#include "common.h"

U16 gCmdIndex;
//return total length
U16 CM_paraPackU32(PPARAM pParam, U32 paraType, U32 paraValue)
{   
    pParam->paraType = paraType;
    pParam->paraLength = sizeof(U32);
    *((U32*)pParam->paraValue) = paraValue;
    return roundup8(sizeof(U32)*2 + sizeof(U32));
}

U16 CM_paraPackError(PPARAM pParam, U32 errorCode)
{
    U16 len = 0;
    len = CM_paraPackU32(pParam,PARA_TYPE_RESULT,PARA_VALUE_RESULT_FAILED);
    len+= CM_paraPackU32( (PPARAM)((U8*)pParam+len),PARA_TYPE_ERROR_CODE,errorCode);
    return len;
}


U16 CM_paraPackException(PPARAM pParam, U32 exCode)
{
    U16 len = 0;
    len = CM_paraPackU32(pParam,PARA_TYPE_RESULT,PARA_VALUE_STATUS_EX);
    len+= CM_paraPackU32( (PPARAM)((U8*)pParam+len),PARA_TYPE_EXCEPTION_CODE,exCode);
    return len;
}

/*
Function: CM_paraPackPara
Parameters:
    PPARAM *ppParam: [IN,OUT] pointer to current parameter, move to next parameter after completed.
    U32 paraType, U32 paraLength : [IN] 
    U8** pParaValue [OUT]  the pointer to a pointer which represent the start address of parameter value .  
        Caller must fill actual parameter value outside this function.
        The benefit of this implementation(  no memcpy inside) is to avoid memcpy twice for long parameter. For Example:

        The normal steps to fill  parameter value  in the format of a big structure: 
         1) create a temporay structure , fill value one by one.  
         2) copy the structure to adderess of parameter value.

        New approach if using implementation in this function can be that:
         1)  After calling this function caller can get  address of parameter value  
         2)  caller can cast  structure on this address directly and fill value one by one. 
     
Return:
     total length of current parameter 

*/
U32 CM_paraPackPara(PPARAM *ppParam, U32 paraType, U32 paraLength, U8** pParaValue)
{
    PPARAM pParam = *ppParam;
    U32 len = roundup8(sizeof(PARAM) + paraLength);
    pParam->paraType = paraType;
    pParam->paraLength = paraLength;
    *pParaValue = pParam->paraValue;
    *ppParam = (PPARAM)((U8*)(*ppParam) + len);
    return len;

}


RESULT CM_SendMsg_noPara(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex)
{
    U64 msgbuff[MSG_BUFF_SIZE/8]= {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    
    pCmdHeader->cmdLength = 0; 
    
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
}

RESULT CM_SendMsg_1Para(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex,
    U32 paraType,
    U32 paraLength,
    U8 *paraValue)
{
    U64 msgbuff[MSG_BUFF_SIZE/8]= {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    PPARAM pParam = (PPARAM)(pCmdHeader + 1);
    U8 *pValue = NULL;

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    pCmdHeader->cmdLength = 0; 

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType,paraLength,&pValue);
    memcpy(pValue, paraValue, paraLength);
    
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
}


RESULT CM_SendMsg_2Para(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex,
    U32 paraType1,
    U32 paraLength1,
    U8 *paraValue1,
    U32 paraType2,
    U32 paraLength2,
    U8 *paraValue2
    )
{
    U64 msgbuff[MSG_BUFF_SIZE/8]= {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    PPARAM pParam = (PPARAM)(pCmdHeader + 1);
    U8 *pValue = NULL;

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    
    pCmdHeader->cmdLength = 0; 

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType1,paraLength1,&pValue);
    memcpy(pValue, paraValue1, paraLength1);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType2,paraLength2,&pValue);
    memcpy(pValue, paraValue2, paraLength2);
    
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
}



RESULT CM_SendMsg_3Para(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex,
    U32 paraType1,
    U32 paraLength1,
    U8 *paraValue1,
    U32 paraType2,
    U32 paraLength2,
    U8 *paraValue2,
    U32 paraType3,
    U32 paraLength3,
    U8 *paraValue3
    )
{
    U64 msgbuff[MSG_BUFF_SIZE/8] = {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    PPARAM pParam = (PPARAM)(pCmdHeader + 1);
    U8 *pValue = NULL;

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    
    pCmdHeader->cmdLength = 0; 

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType1,paraLength1,&pValue);
    memcpy(pValue, paraValue1, paraLength1);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType2,paraLength2,&pValue);
    memcpy(pValue, paraValue2, paraLength2);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType3,paraLength3,&pValue);
    memcpy(pValue, paraValue3, paraLength3);
    
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
   
}

RESULT CM_SendMsg_4Para(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex,
    U32 paraType1,
    U32 paraLength1,
    U8 *paraValue1,
    U32 paraType2,
    U32 paraLength2,
    U8 *paraValue2,
    U32 paraType3,
    U32 paraLength3,
    U8 *paraValue3,
    U32 paraType4,
    U32 paraLength4,
    U8 *paraValue4
    )
{
    U64 msgbuff[MSG_BUFF_SIZE/8] = {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    PPARAM pParam = (PPARAM)(pCmdHeader + 1);
    U8 *pValue = NULL;

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    
    pCmdHeader->cmdLength = 0; 

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType1,paraLength1,&pValue);
    memcpy(pValue, paraValue1, paraLength1);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType2,paraLength2,&pValue);
    memcpy(pValue, paraValue2, paraLength2);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType3,paraLength3,&pValue);
    memcpy(pValue, paraValue3, paraLength3);
    
    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType4,paraLength4,&pValue);
    memcpy(pValue, paraValue4, paraLength4);
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
   
}

RESULT CM_SendMsg_5Para(
    U16 dstID,
    U16 srcID,
    U16 msgType,
    U16 cmdType,
    U16 cmdCode,
    U16 cmdIndex,
    U32 paraType1,
    U32 paraLength1,
    U8 *paraValue1,
    U32 paraType2,
    U32 paraLength2,
    U8 *paraValue2,
    U32 paraType3,
    U32 paraLength3,
    U8 *paraValue3,
    U32 paraType4,
    U32 paraLength4,
    U8 *paraValue4,
    U32 paraType5,
    U32 paraLength5,
    U8 *paraValue5

    )
{
    U64 msgbuff[MSG_BUFF_SIZE/8] = {0};
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    PPARAM pParam = (PPARAM)(pCmdHeader + 1);
    U8 *pValue = NULL;

    pMsgHeader->dstID = dstID;
    pMsgHeader->srcID = srcID;
    pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
    pMsgHeader->msgType = msgType;

    pCmdHeader->cmdType = cmdType;
    pCmdHeader->cmdCode = cmdCode;
    pCmdHeader->cmdIndex = cmdIndex;
    
    pCmdHeader->cmdLength = 0; 

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType1,paraLength1,&pValue);
    memcpy(pValue, paraValue1, paraLength1);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType2,paraLength2,&pValue);
    memcpy(pValue, paraValue2, paraLength2);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType3,paraLength3,&pValue);
    memcpy(pValue, paraValue3, paraLength3);
    
    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType4,paraLength4,&pValue);
    memcpy(pValue, paraValue4, paraLength4);

    pCmdHeader->cmdLength += CM_paraPackPara(&pParam,paraType5,paraLength5,&pValue);
    memcpy(pValue, paraValue5, paraLength5);
    pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
    return(CM_sendMsg(pMsgHeader,pCmdHeader));
   
}
/*
Function : CM_paraUnpackPara

Description: Used to unpack parameters step by step. One parameter echo call. 

parameters:
    PPARAM *pParameters : [IN,OUT], pointer to left parameters, move to next parameter after completed
    U32 *length [IN, OUT], pointer to left length.

    U32* pParaType, U32* pParalength, U8** pParaValue : [OUT] the unpacked parameter .

Return:
    RC_FAIL if error encounted
*/


UNPACK_RESULT CM_paraUnpackPara(PPARAM *ppParameters, U32 *length, U32* pParaType, U32* pParalength, U8** pParaValue )
{
        PPARAM pParam = *ppParameters;
        U32 len =sizeof(PARAM) + pParam->paraLength; 
              
        if(((*length) >= len) && pParam)   //   valid
        {        
            *pParaType = pParam->paraType;
            *pParalength = pParam->paraLength;
            *pParaValue = pParam->paraValue;

            *ppParameters = (PPARAM)((U8*) (*ppParameters) + roundup8(len));
            
            if((*length) > roundup8(len))
            {
                *length = *length - roundup8(len);                 
            }
            else
            {
                *length = 0;
            }
            
            return UNPACK_OK;
            
        }
        else if (*length == 0)
        {
            return UNPACK_END;
        }
        else
        {    
            return UNPACK_ERROR;
        }
            
}


PARADECODER CM_searchDecoderByType(PARADECODERMAP *pDTable, U32 dTableSize, U32 paraType)
{
    int i;
    for(i=0;i<dTableSize;  i++)
    {
        if(pDTable[i].paraType == paraType)
            return pDTable[i].decoder;

    }
    return NULL;
}

RESULT CM_paraListDecoder(PCMDHEADER pCmd,PCMDHEADER pAck, PARADECODERMAP *pDTable, U32 dTableSize,void* pValueStorage, BOOL bDiscardUnknownPara)
{
    PPARAM pParam =(PPARAM)(pCmd+1);
    U32 len = pCmd->cmdLength;
    U32 paraType;
    U32 paraLength;
    U8* paraValue;
    UNPACK_RESULT uprc; 
    ERROR_CODE error=PARA_VALUE_ERROR_NO_ERROR;
    PARADECODER paraDecoder = NULL;
    
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        paraDecoder = CM_searchDecoderByType(pDTable,dTableSize,paraType);
        if(paraDecoder == NULL) // not found
        {
            if(!bDiscardUnknownPara)
            {
                error = PARA_VALUE_ERROR_UNKNOWN_PARATYPE;
            }
        }
        else
        { 
            error = paraDecoder(pValueStorage, paraValue, paraLength);
          
        }

        if(error != PARA_VALUE_ERROR_NO_ERROR)
            break;
    }

    if(uprc == UNPACK_ERROR)   
    {    
        if(pAck)
        {
            pAck->cmdLength = CM_paraPackError((PPARAM)(pAck+1), PARA_VALUE_ERROR_ILLEGAL_PARA_STRUCT);

        }
        dbgprintf(DEBUG_ERROR,stderr,"Error in cmdType=%02x cmdCode=%04x. Error=%x\n",pCmd->cmdType,pCmd->cmdCode,PARA_VALUE_ERROR_ILLEGAL_PARA_STRUCT);
        return RC_FAIL;
    }
    else
    {
        if(error != PARA_VALUE_ERROR_NO_ERROR)
        {
            if(pAck)
            {
                pAck->cmdLength = CM_paraPackError((PPARAM)(pAck+1), error);
            }
            dbgprintf(DEBUG_ERROR,stderr,"Error in cmdType=%02x cmdCode=%04x. Error=%x\n",pCmd->cmdType,pCmd->cmdCode,error);
            return RC_FAIL;
        }     
    }

    return RC_OK;
}

RESULT CM_paraGetValueByType(PPARAM parameters, U32 length, U32 paraType, U32* paralength, U8** paraValue )
{
    PPARAM pParam = parameters;
    U32 len =0; 
    U32 total_len = 0;
    BOOL bFound = FALSE;
    
    while(length > total_len)
    {    
        pParam = (PPARAM)((U8*)pParam + roundup8(len));
        len = sizeof(PARAM) + pParam->paraLength;
        total_len +=roundup8(len);
        
        if(pParam->paraType == paraType)
        {
            bFound = TRUE;
            break;
        } 
    }

    if( bFound && (length >=(total_len-roundup8(len) +len)) )  // found and  valid
    {        
        *paralength = pParam->paraLength;
        *paraValue = pParam->paraValue;
        return RC_OK;
    }
    else
    {

        return RC_FAIL;
    }
        
}

void CM_cmdDispatcher(CMMODINFO *pCmModInfo)
{
	U64 msgbuff[MSG_BUFF_SIZE/8];
    //int rc;
    PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
    PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );
    //U16 dstID;
    U16 srcID;
    U16 msgType;
    //U16 msgLength;
    //PPARAM pParam;
   
    
    while(TRUE)
    {
        MSG_read(pCmModInfo->ModID,pMsgHeader,pCmdHeader);
        //dstID = pMsgHeader->dstID;
        srcID = pMsgHeader->srcID;
        msgType = pMsgHeader->msgType;
        //msgLength = pMsgHeader->msgLength;

        if(msgType == MSG_TYPE_COMMAND)
        {                        
            U64 respBuff[MSG_BUFF_SIZE/8];
            U32 needAck = TRUE;
            PMSGHEADER pAckMsgHeader =(PMSGHEADER) respBuff;
            PCMDHEADER pAckHeader = (PCMDHEADER)( ((U8*)respBuff) + sizeof(MSGHEADER) );
            pAckMsgHeader->dstID = srcID;
            pAckMsgHeader->srcID = pCmModInfo->ModID;
            pAckMsgHeader->msgType = MSG_TYPE_COMMAND;
            pAckMsgHeader->mType = get_mtype(pAckMsgHeader->dstID);
            pAckHeader->cmdCode = pCmdHeader->cmdCode;
            pAckHeader->cmdIndex = pCmdHeader->cmdIndex;
            pAckHeader->cmdLength = 0;

            switch(pCmdHeader->cmdType)
            {
                case CMD_SET:
                    pAckHeader->cmdType = CMD_SET_RESPONSE;
                    if(get_mtype(srcID) == MSGQ_TYPE_MSG ) // need not ack for internal set message
                        needAck = FALSE;
                    if(pCmModInfo->setProc)
                        pCmModInfo->setProc(pCmdHeader,pAckHeader);
                    break;
                case CMD_GET:
                    pAckHeader->cmdType = CMD_GET_RESPONSE;
                    if(pCmModInfo->getProc)
                        pCmModInfo->getProc(pCmdHeader,pAckHeader);
                    break;
                case CMD_EVENT:
                    //need not ack
                    needAck = FALSE;
                    if(pCmModInfo->eventProc)
                        pCmModInfo->eventProc(pCmdHeader);
                    break;
                case CMD_SET_RESPONSE:
                    needAck = FALSE;
                    if(pCmModInfo->setAckProc)
                        pCmModInfo->setAckProc(pCmdHeader);
                    break;
                case CMD_GET_RESPONSE:
                    needAck = FALSE;
                    if(pCmModInfo->getAckProc)
                        pCmModInfo->getAckProc(pCmdHeader);
                    break;
                case CMD_EVENT_RESPONSE:
                    //need not ack
                    needAck = FALSE;
                    if(pCmModInfo->eventAckProc)
                        pCmModInfo->eventAckProc(pCmdHeader);
                    break;    
                default:
                    pAckHeader->cmdType = CMD_GENERAL_RESPONSE;//pCmdHeader->cmdType;  
                    pAckHeader->cmdLength = CM_paraPackError((PPARAM)(pAckHeader+1), PARA_VALUE_ERROR_UNKNOWN_CMDTYPE);
                    dbgprintf(DEBUG_ERROR,stderr,"Unknown cmd type 0x%04x from %d\n",pCmdHeader->cmdType,srcID);
                    break;

            }   

            if(needAck)
            {
                
                pAckMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pAckHeader->cmdLength; 
                CM_sendMsg(pAckMsgHeader, pAckHeader);
            }

            if(pCmModInfo->postProc)
            {                
                pCmModInfo->postProc();
            }
        }
        else if(msgType == MSG_TYPE_TICK)
        {
            if(pCmModInfo->useTimer)
            {
                MOD_timerProc(pCmModInfo->ModID);
            }
            else
            {
                // do nothing
                dbgprintf(DEBUG_ERROR,stderr,"Unknown message type %04x from %04x",
                    msgType,srcID);
            }
        }
        else if(msgType == MSG_TYPE_INTERNAL)  // for internal date
        {
            switch(pCmdHeader->cmdType)
            {
                case CMD_EVENT:                    
                    if(pCmModInfo->eventProc)
                        pCmModInfo->eventProc(pCmdHeader);
                    break;
                default:
                    //pAckHeader->cmdType = CMD_SET_RESPONSE;//pCmdHeader->cmdType;  
                    //pAckHeader->cmdLength = CM_paraPackError((PPARAM)(pAckHeader+1), PARA_VALUE_ERROR_UNKNOWN_CMDTYPE);
                    dbgprintf(DEBUG_ERROR,stderr,"Unknown internal cmd type 0x%04x from %d\n",pCmdHeader->cmdType,srcID);
                    break;

            }   

        }
        else
        {
            // do nothing
            dbgprintf(DEBUG_ERROR,stderr,"Unknown message type %04x from %04x",
                    msgType,srcID);

        }
    }
}



ERROR_CODE CM_decodeTimestamp(void *h, U8* paraValue, U32 paraLength )
{
    UEIDPARALIST *buff = (UEIDPARALIST *)h;
    if(paraLength==sizeof(U64))
    {
         buff->uptime= *(U64*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else 
    {
        return PARA_VALUE_ERROR_INVALID_PARALENGTH;
    }
}

ERROR_CODE CM_decodeIMSI(void *h, U8* paraValue, U32 paraLength )
{
    UEIDPARALIST *buff = (UEIDPARALIST *)h;
    if(paraLength==16)
    {
        paraValue[15]='\0';
        buff->imsirecord = (char*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else 
    {
        return PARA_VALUE_ERROR_INVALID_PARALENGTH;
    }
}

ERROR_CODE CM_decodeIMEI(void *h, U8* paraValue, U32 paraLength )
{
    UEIDPARALIST *buff = (UEIDPARALIST *)h;

    if(paraLength==16)
    {        
        paraValue[15]='\0';
        buff->imeirecord = (char*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else if(paraLength==9)
    {        
        paraValue[9]='\0';
        buff->imeirecord = (char*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else 
    {
        return PARA_VALUE_ERROR_INVALID_PARALENGTH;
    }
}
//use for LTE
ERROR_CODE CM_decodeSlotId(void *h, U8* paraValue, U32 paraLength )
{
    UEIDPARALIST *buff = (UEIDPARALIST *)h;
    if(paraLength== sizeof(U8))
    {
        buff->slotId = *(U8*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else 
    {
        return PARA_VALUE_ERROR_INVALID_PARALENGTH;
    }
}

ERROR_CODE CM_decodeLac(void *h, U8* paraValue, U32 paraLength)
{
    UEIDPARALIST *buff = (UEIDPARALIST *)h;
    if(paraLength== sizeof(U16))
    {
        buff->lac = *(U16*)paraValue;
        return PARA_VALUE_ERROR_NO_ERROR;
    }
    else 
    {
        return PARA_VALUE_ERROR_INVALID_PARALENGTH;
    }
}

RESULT CM_sendMsg(MSGHEADER * pMsgHeader,void * pMsgPayload)
{
    U16 peerID ; 

    if( get_mtype(pMsgHeader->dstID) != MSGQ_TYPE_MSG )
    {    
        peerID = MODULE_MESSAGE;
    }
    else
    {
        peerID = pMsgHeader->dstID;
    }

    return (MSG_send(peerID,pMsgHeader,pMsgPayload));
}

const char *restartCauseFile = "/mnt/usr/restartCause.tmp";
RESULT createRestartCauseFileByCode(U16 code)
{
    if (access(restartCauseFile, F_OK) == 0)
    {
        unlink(restartCauseFile);
    }
    FILE *fd = NULL;
    fd = fopen(restartCauseFile, "a");
    if (fd == NULL)
    {
        return RC_FAIL;
    }
    fprintf(fd, "%d", code);
    fclose(fd);
    return RC_OK;
}


